using System;
using System.Collections.Generic;
using System.Windows.Forms;
using PasswordGenerator;
using RedGate.SQLCompare.Engine;
using RedGate.SQLDataGenerator.Engine.Generators;
using RedGate.SQLDataGenerator.Engine.Project;

namespace PasswordGenerator
{
    public partial class PasswordGeneratorUI : UserControl, IGeneratorSimpleUI
    {
        private readonly PasswordGenerator m_Generator;
        private readonly GeneratorParameters m_Parameters;
        private ModifiedGeneratorDataEventHandler m_Modified;
        private SDGTable m_Table;
        private SDGField m_Field;
        private bool m_Loading;

        public PasswordGeneratorUI(PasswordGenerator generator, GeneratorParameters parameters)
        {
            m_Generator = generator;
            m_Parameters = parameters;
            InitializeComponent();
        }

        public void ConfigureFieldAndTable(SDGTable table, SDGField field)
        {
            m_Table = table;
            m_Field = field;

            m_Loading = true;

            List<ComboEntry> saltColumns = new List<ComboEntry>();
            List<ComboEntry> passwordColumns = new List<ComboEntry>();
            List<ComboEntry> encryptionTypes = new List<ComboEntry>();
            List<ComboEntry> saltCombiningMethods = new List<ComboEntry>();
            List<ComboEntry> passwordTextEncodings = new List<ComboEntry>();


            saltColumns.Add(new ComboEntry("No salt", String.Empty));
            passwordColumns.Add(new ComboEntry("Random password string", String.Empty));

            foreach (Field f in m_Parameters.Table.Fields)
            {
                ComboEntry ce = new ComboEntry(f.Name, f.Name);
                saltColumns.Add(ce);
                passwordColumns.Add(ce);
            }

            foreach (EncryptionType et in Enum.GetValues(typeof(EncryptionType)))
            {
                encryptionTypes.Add(new ComboEntry(
                                        Enum.GetName(typeof(EncryptionType), et), et));
            }

            foreach (PasswordTextEncoding pte in Enum.GetValues(typeof(PasswordTextEncoding)))
            {
                passwordTextEncodings.Add(new ComboEntry(
                                              Enum.GetName(typeof(PasswordTextEncoding), pte), pte));
            }

            saltCombiningMethods.Add(new ComboEntry("Append the salt to the password", SaltCombiningMethod.AppendText));
            saltCombiningMethods.Add(new ComboEntry("Prepend the salt to the password", SaltCombiningMethod.PrependText));

            m_SaltColumn.DataSource = saltColumns;
            m_PasswordColumn.DataSource = passwordColumns;
            m_EncryptionType.DataSource = encryptionTypes;
            m_SaltCombiningMethod.DataSource = saltCombiningMethods;
            m_PasswordTextEncoding.DataSource = passwordTextEncodings;


            SelectItem(m_SaltColumn, m_Generator.SaltColumn);
            SelectItem(m_PasswordColumn, m_Generator.PasswordTextColumn);
            SelectItem(m_EncryptionType, m_Generator.EncryptionType);
            SelectItem(m_SaltCombiningMethod, m_Generator.SaltCombiningMethod);
            SelectItem(m_PasswordTextEncoding, m_Generator.PasswordTextEncoding);

            m_Loading = false;
        }

        private static void SelectItem(ComboBox comboBox, object val)
        {
            List<ComboEntry> ds = comboBox.DataSource as List<ComboEntry>;
            if (ds != null && ds.Count > 0)
            {
                for (int i = 0; i < ds.Count; i++)
                {
                    ComboEntry entry = ds[i];

                    if (entry.Value.ToString() == val.ToString())
                    {
                        comboBox.SelectedIndex = i;
                        return;
                    }
                }

                comboBox.SelectedIndex = 0;
            }
        }

        public ModifiedGeneratorDataEventHandler Modified
        {
            get { return m_Modified; }
            set { m_Modified = value; }
        }

        private class ComboEntry
        {
            private readonly string m_Name;
            private readonly object m_Value;
            
            public object Value
            {
                get { return m_Value; }
            }

            public ComboEntry(string name, object value)
            {
                m_Name = name;
                m_Value = value;
            }

            public override string ToString()
            {
                return m_Name;
            }
        }

        private void SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!m_Loading)
            {
                m_Generator.SaltColumn = (string) ((ComboEntry) m_SaltColumn.SelectedItem).Value;
                m_Generator.PasswordTextColumn = (string) ((ComboEntry) m_PasswordColumn.SelectedItem).Value;
                m_Generator.EncryptionType = (EncryptionType) ((ComboEntry) m_EncryptionType.SelectedItem).Value;
                m_Generator.SaltCombiningMethod =
                    (SaltCombiningMethod) ((ComboEntry) m_SaltCombiningMethod.SelectedItem).Value;
                m_Generator.PasswordTextEncoding =
                    (PasswordTextEncoding) ((ComboEntry) m_PasswordTextEncoding.SelectedItem).Value;

                if (Modified != null)
                {
                    Modified(this, new ModifiedGeneratorDataEventArgs(m_Table, m_Field, false));
                }
            }
        }
    }
}